import json
from channels.generic.websocket import AsyncWebsocketConsumer
from channels.db import database_sync_to_async
from django.contrib.auth.models import User
from .models import Battle
from .message_protocol import MessageType, MessageProtocol

class BattleConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        self.battle_id = self.scope['url_route']['kwargs']['battle_id']
        self.battle_group_name = f'battle_{self.battle_id}'

        # 获取用户信息
        self.user = self.scope['user']

        # 检查用户是否有权限加入该战斗
        if not self.user.is_authenticated:
            await self.close()
            return

        # 检查用户是否有权限查看该战斗
        has_permission = await self.check_battle_permission()
        if not has_permission:
            await self.close()
            return

        # 加入战斗组
        await self.channel_layer.group_add(
            self.battle_group_name,
            self.channel_name
        )

        await self.accept()

        # 发送连接成功消息
        await self.send(text_data=json.dumps({
            'type': 'connection_established',
            'message': '已连接到战斗WebSocket',
            'battle_id': self.battle_id,
            'user_id': self.user.id,
            'username': self.user.username
        }))

    async def disconnect(self, close_code):
        # 离开战斗组
        await self.channel_layer.group_discard(
            self.battle_group_name,
            self.channel_name
        )

    async def receive(self, text_data):
        # 接收前端发送的消息
        try:
            text_data_json = json.loads(text_data)
            message_type = text_data_json.get('type')

            # 根据消息类型处理
            if message_type == 'command':
                # 处理命令消息 - 统一使用CommandModel格式
                command_data = text_data_json.get('command', {})

                # 直接广播命令到战斗组
                await self.channel_layer.group_send(
                    self.battle_group_name,
                    {
                        'type': 'battle_command',
                        'command': command_data,
                        'user_id': self.user.id,
                        'username': self.user.username
                    }
                )

        except json.JSONDecodeError:
            # 发送错误消息
            await self.send(text_data=json.dumps({
                'type': 'error',
                'message': '无效的JSON格式'
            }))
        except Exception as e:
            # 发送错误消息
            await self.send(text_data=json.dumps({
                'type': 'error',
                'message': f'处理消息时出错: {str(e)}'
            }))

    # 处理战斗命令消息
    async def battle_command(self, event):
        # 发送命令消息给WebSocket客户端
        await self.send(text_data=json.dumps({
            'type': 'command',
            'command': event['command'],
            'user_id': event['user_id'],
            'username': event['username']
        }))

    # 处理战斗更新消息
    async def battle_update(self, event):
        # 发送战斗更新消息给WebSocket客户端
        await self.send(text_data=json.dumps({
            'type': 'battle_update',
            'message': event['message']
        }))

    # 检查用户是否有权限查看该战斗
    @database_sync_to_async
    def check_battle_permission_sync(self):
        try:
            battle = Battle.objects.get(id=self.battle_id)
            # 如果战斗是公开的，所有用户都可以查看
            if battle.is_public:
                return True
            # 如果战斗不公开，只有参战玩家和管理员可以查看
            return (self.user == battle.player1 or
                    self.user == battle.player2 or
                    self.user.is_staff)
        except Battle.DoesNotExist:
            return False

    async def check_battle_permission(self):
        return await self.check_battle_permission_sync()

    # 验证命令
    @database_sync_to_async
    def validate_command_sync(self, command_data):
        # TODO: 实现命令验证逻辑
        # 目前简单返回验证通过
        return True, "命令验证通过"

    async def validate_command(self, command_data):
        return await self.validate_command_sync(command_data)
